def combination_sum(candidates, target):
    def dfs(start, path, remain):
        if remain == 0:
            result.append(path.copy())  # 找到有效组合
            return
        for i in range(start, len(candidates)):
            if candidates[i] > remain:
                continue  # 跳过超过剩余值的候选数
            path.append(candidates[i])  # 选择当前数
            dfs(i, path, remain - candidates[i])  # 递归搜索
            path.pop()  # 回溯，撤销选择

    result = []
    dfs(0, [], target)
    return result
# 测试用例
candidates = [2, 3, 5]
target = 8
print(combination_sum(candidates, target))

# dfs 核心在于递归、回溯、递归边界
# 选择一个指定的方向一直走碰壁后回溯一个单位换方向，往复得出答案
# dfs可以记录解决问题所有的路径。故而对于有多少种走法（需要列举具体内容），多少种排列的问题非常适用
# 探索所有解
# 对候选数据组成目标数的问题，我们需要得到组成目标数的所有组合方法且候选数可以重复使用
# 显而易见的目标数可作为边界
# if detected_number > 8: 放弃这条路径;

